package com.vegetable.modules.service.bank.convert;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.vegetable.modules.entity.finance.Transactions;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * 建行流水标准化字段输出
 */
@Slf4j
public class CCBConverter extends BankGenerator{
    private static final String bankMark = "CCB";
    public List<Transactions> convert(MultipartFile file) throws Exception {
        List<Transactions> result  = convertA(file);
        if(CollectionUtil.isEmpty(result)){
            result = convertB(file);
        }
        return result;
    }

    public List<Transactions> convertA(MultipartFile file) throws Exception {
        List<Transactions> result = new ArrayList<>();
        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            int lastRow = sheet.getLastRowNum();
            // 首先使用方案A
            for(int i = 10; i < lastRow; i++){
                Row currentR = sheet.getRow(i);
                Transactions thisT = getTransactions(currentR);
                result.add(thisT);
            }
        }catch (Exception e){
            log.error("转换建行流水发生异常--->", e);
            return null;
        }
        return result;
    }

    public List<Transactions> convertB(MultipartFile file) throws Exception {
        List<Transactions> result = new ArrayList<>();
        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            int lastRow = sheet.getLastRowNum();
            // 如果没结果，则使用方案B
            for(int i = 1; i <= lastRow; i++){
                Row currentR = sheet.getRow(i);
                Transactions thisT = getTransactionsB(currentR);
                result.add(thisT);
            }
        }catch (Exception e){
            log.error("转换建行流水发生异常--->", e);
            return null;
        }
        return result;
    }

    @NotNull
    private Transactions getTransactions(Row currentR) throws Exception {
        Transactions thisT = new Transactions();
        thisT.setTradingType(getDoubleCell(currentR, 1) > 0 ? "EXPENSE" : "INCOME");
        thisT.setTradingTime(DateUtil.parse(getStringCell(currentR, 0), "yyyyMMdd HH:mm:ss"));
        thisT.setTradingAmount("INCOME".equals(thisT.getTradingType()) ? getBCCell(currentR, 2) : getBCCell(currentR, 1));
        thisT.setBalanceAmount(getBCCell(currentR, 3));
        thisT.setBankName(getStringCell(currentR, 7));
        thisT.setBankNo(getStringCell(currentR, 6));
        thisT.setCounterparty(getStringCell(currentR,5));
        thisT.setTradingDescription(getStringCell(currentR,9));
        thisT.setRemark(getStringCell(currentR, 10));
        thisT.setTradingNo(Transactions.generateUniqueFlowId(thisT));
        thisT.setChannel(bankMark);
        return thisT;
    }

    @NotNull
    private Transactions getTransactionsB(Row currentR) throws Exception {
        Transactions thisT = new Transactions();
        thisT.setTradingType(getDoubleCell(currentR, 3) > 0 ? "EXPENSE" : "INCOME");
        thisT.setTradingTime(DateUtil.parse(getStringCell(currentR, 2), "yyyyMMdd HH:mm:ss"));
        thisT.setTradingAmount("INCOME".equals(thisT.getTradingType()) ? getBCCell(currentR, 4) : getBCCell(currentR, 3));
        thisT.setBalanceAmount(getBCCell(currentR, 5));
        thisT.setBankName(getStringCell(currentR, 9));
        thisT.setBankNo(getStringCell(currentR, 8));
        thisT.setCounterparty(getStringCell(currentR,7));
        thisT.setTradingDescription(getStringCell(currentR,11));
        thisT.setRemark(getStringCell(currentR, 12));
        thisT.setTradingNo(Transactions.generateUniqueFlowId(thisT));
        thisT.setChannel(bankMark);
        return thisT;
    }

}
